﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace HaSdkDemo
{
    public partial class Form1 : Form
    {
        private IntPtr g_cam = IntPtr.Zero;
        private List<string> ipList = new List<string>();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var path = AppDomain.CurrentDomain.BaseDirectory;
            path = path.Substring(0, path.Length - 1);
            axHaCamera1.FullImageSaveDir = path;
            axHaCamera1.SetIsSaveDecodeImage(true);
            axHaCamera1.OnLPRFindDeviceInfoOut += AxHaCamera1_OnLPRFindDeviceInfoOut;
            textBoxQueryFrom.Text = DateTime.Now.AddHours(-1).ToString("yyyy-MM-dd HH:mm:ss");
            textBoxQueryTo.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

        }

        private void AxHaCamera1_OnLPRFindDeviceInfoOut(object sender, AxHaCameraLib._DHaCameraEvents_OnLPRFindDeviceInfoOutEvent e)
        {
            if (e.system != "PARK")
            {
                return;
            }

            if (ipList.Contains(e.ipAddress))
            {
                return;
            }

            //var msg =
            //    $"ip:{e.ipAddress}, mac:{e.mac}, mask:{e.netMask}, manufacturer: {e.manufacturer}, platform: {e.platform}, sys: {e.system}, ver:{e.version}";
            //Log(msg);


            axHaCamera1.VzLPRClientOpen(e.ipAddress, 9527, "", "");
            var start = DateTime.Now;
            while (!axHaCamera1.IsConnected())
            {
                Thread.Sleep(50);
                if (DateTime.Now - start > TimeSpan.FromSeconds(3))
                {
                    break;
                }
            }
            if (axHaCamera1.IsConnected())
            {
                var userData = axHaCamera1.VzLPRReadUserData(0);
                var msg = string.Format("userData: {0}", userData);
                Log(msg);
            }
            else
            {
                Log(string.Format("connect to {0} failed", e.ipAddress));
            }

            axHaCamera1.VzLPRClientClose(0);
            ipList.Add(e.ipAddress);
        }

        private object _locker = new object();
        private bool _saveVideoAsImage;

        public bool SaveVideoAsImage
        {
            get
            {
                lock (_locker)
                {
                    return _saveVideoAsImage;
                }

            }
            set
            {
                lock (_locker)
                {
                    _saveVideoAsImage = value;
                }
            }
        }


        DateTime _lastSaveTime = DateTime.MinValue;
        private void onImageDecoded(IntPtr cam, IntPtr rgb, int width, int height, int userParm)
        {
            if (SaveVideoAsImage)
            {
                var now = DateTime.Now;
                if (now - _lastSaveTime >= TimeSpan.FromSeconds(1))
                {
                    var buffer = Marshal.AllocHGlobal(2 * 1024 * 1024);
                    uint len = 0;
                    //HaSdk.HA_EncodeJpeg(rgb, (uint)width, (uint)height, buffer, ref len);
                    if (len > 0)
                    {
                        var bytes = new byte[len];
                        Marshal.Copy(buffer, bytes, 0, (int)len);

                        var fileName = now.ToString("s").Replace(":", ".") + ".jpg";
                        var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "images");
                        path = Path.Combine(path, fileName);
                        var dir = Path.GetDirectoryName(path);
                        if (!Directory.Exists(dir))
                        {
                            Directory.CreateDirectory(dir);
                        }
                        File.WriteAllBytes(path, bytes);
                        _lastSaveTime = now;
                    }

                    Marshal.FreeHGlobal(buffer);
                }

            }

        }

        private void OnDataReceived(IntPtr cam, string ip, ushort port, int dataType, IntPtr data, uint dataLen, int usrParam)
        {
            //switch (dataType)
            //{
            //    case HaSdkConstants.MESSAGE_ID_CAR:
            //        var pkg = (pkg_vehicle)Marshal.PtrToStructure(data, typeof(pkg_vehicle));
            //        ShowPlate(pkg);

            //        break;
            //}

        }

        public string ConvertColor(int index)
        {
            switch (index)
            {
                case 1:
                    return "蓝";
                case 2:
                    return "黄";
                case 3:
                    return "白";
                case 4:
                    return "黑";
                case 5:
                    return "绿";
                default:
                    return "";
            }
        }

        private void ShowPlate(PlateCaptured plate)
        {
            Action<PlateCaptured> action = x =>
            {
                labelPlate.Text = x.hphm + ConvertColor(x.colorIndex);
                if (x.image != null)
                {
                    ShowImage(pictureBoxCapture, x.image);
                }

                if (x.plateImage != null)
                {
                    ShowImage(pictureBoxPlate, x.plateImage);
                }

            };
            this.Invoke(action, plate);
        }

        private static void ShowImage(PictureBox pictureBox, Image img)
        {
            var old = pictureBox.Image;
            pictureBox.Image = img;
            if (old != null)
            {
                old.Dispose();
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBoxIp.Text))
            {
                MessageBox.Show("请输入有效的ip地址");
                return;
            }




            //int errorNum = 0;
            var handle = axHaCamera1.VzLPRClientOpen(textBoxIp.Text, 9527, "", "");
            if (handle == 0)
            {
                MessageBox.Show("connect error");
            }
            else
            {
                panelCommands.Enabled = true;
                //开始显示实时画面
                //如果不需要显示实时画面，将第二个参数传IntPtr.Zero
                axHaCamera1.VzLPRClientStartPlay(handle, 0);
                panelSerialCommand.Enabled = true;

            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            //if (HaSdk.HA_Connected(g_cam))
            //{
            //    var ctrl = new CamCtrl();
            //    HaSdk.HA_GetCamParam(g_cam, ref ctrl);
            //    var msg = string.Format("stand = {0}, shut = {1}, imgSaturability = {2}", ctrl.autoCtrl.standard, ctrl.autoCtrl.maxShut, ctrl.imgEnhance.imgSaturability);
            //    Log(msg);
            //}
        }

        private void Log(string msg)
        {
            listBox1.Items.Insert(0, DateTime.Now + ": " + msg);
        }

        private void button7_Click(object sender, EventArgs e)
        {

            axHaCamera1.VzLPRClientQueryWlistByPlate("", 0);

        }

        private void button3_Click(object sender, EventArgs e)
        {
            //var ctrl = new CamCtrl();

            //int ret = HaSdk.HA_GetCamParam(g_cam, ref ctrl);
            //var msg = string.Format("HA_GetCamParam ret = {0}", ret);
            //Log(msg);
            //msg = string.Format("get stand = {0}, shut = {1}, imgSaturability = {2}", ctrl.autoCtrl.standard, ctrl.autoCtrl.maxShut, ctrl.imgEnhance.imgSaturability);
            //Log(msg);

            //ctrl.autoCtrl.standard = 150;
            //ctrl.autoCtrl.maxShut = 5000;
            //HaSdk.HA_SetAutoCtrl(g_cam, ref ctrl.autoCtrl);

            //ctrl.imgEnhance.imgSaturability = 150;
            //HaSdk.HA_SetImageEnhance(g_cam, ref ctrl.imgEnhance);
        }

        private void button4_Click(object sender, EventArgs e)
        {

            var fileName = Path.GetTempFileName() + ".jpg";

            var res = axHaCamera1.VzLPRClientCaptureImg(0, fileName);
            if (res)
            {
                Process.Start(fileName);
            }

        }

        private void button6_Click(object sender, EventArgs e)
        {
            var plate = textBoxHphm.Text;

            var result = axHaCamera1.VzLPRClientAddWlist(plate, 0, true, "2016-12-31 12:23:34", false, false, "", 0);
            LogResult(result);

        }

        private void button8_Click(object sender, EventArgs e)
        {
            var result = axHaCamera1.VzLPRWhiteListClear(0);
            LogResult(result);
        }

        private void button9_Click(object sender, EventArgs e)
        {
            bool offline = false;
            axHaCamera1.VzLPRGetOfflineCheck(ref offline);
            var msg = string.Format("工作模式：{0}", offline ? "离线" : "在线");
            Log(msg);
        }

        private void button10_Click(object sender, EventArgs e)
        {
            axHaCamera1.VzLPRSetOfflineCheck(0);
        }

        private void button11_Click(object sender, EventArgs e)
        {
            axHaCamera1.VzLPRCancelOfflineCheck(0);
        }

        private void button12_Click(object sender, EventArgs e)
        {
            var s = axHaCamera1.VzLPRGetSerialNumber(0);
            Log("SN: " + s);
        }

        private void button13_Click(object sender, EventArgs e)
        {
            var s = Guid.NewGuid().ToString();
            axHaCamera1.VzLPRWriteUserData(0, s);
            Log("写入： " + s);
        }

        private void button14_Click(object sender, EventArgs e)
        {
            string code = axHaCamera1.VzLPRReadUserData(0);
            Log("读出：" + code);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            var result = axHaCamera1.VzLPRClientForceTrigger(0);
            LogResult((short)(result ? 0 : -1));
        }


        public void OnConnect(IntPtr cam, string ip, ushort port, int evt, int usrParam)
        {
            switch (evt)
            {
                case 1:
                    EnableButtons(true);
                    break;
                case 2:
                    EnableButtons(false);
                    break;
            }
        }

        private void EnableButtons(bool enable)
        {
            Action<bool> action = b => panelCommands.Enabled = b;
            this.Invoke(action, enable);
        }

        private void button15_Click(object sender, EventArgs e)
        {
            var result = axHaCamera1.VzLPRClientSetIOOutputAuto(0, 0, 500);
            LogResult(result);
        }

        private void LogResult(short result)
        {
            var msg = string.Format("执行结果：{0}", result == 0 ? "成功" : "失败");
            Log(msg);
        }




        private void ShowData(string data)
        {
            Action<string> action = s =>
            {
                var msg = DateTime.Now + " - " + s;
                listBoxSerialReceived.Items.Insert(0, msg);
            };

            this.Invoke(action, data);
        }

        private void button16_Click(object sender, EventArgs e)
        {
            var text = textBoxDataForSerial.Text;
            if (string.IsNullOrEmpty(text) || text.Count(x => x != ' ') % 2 != 0)
            {
                var msg = "请确保数据为偶数个";
                Log(msg);
                return;
            }


            text = text.Replace(" ", "");

            var result = axHaCamera1.VzLPRSerialSend(0, text, (short)text.Length);

            var msgs = "写串口" + (result == 0 ? "成功" : "失败");
            Log(msgs);



        }

        private void button17_Click(object sender, EventArgs e)
        {
            var result = axHaCamera1.VzLPRSerialStart(0, 0);
            if (result == 0)
            {
                panelSerial.Enabled = true;
            }
            var msg = string.Format("串口打开 {0}", result == 0 ? "成功" : "失败");
            Log(msg);
        }

        private void button18_Click(object sender, EventArgs e)
        {
            var result = axHaCamera1.VzLPRSerialStop(0);
            if (result == 0)
            {
                panelSerial.Enabled = false;
            }
        }

        private void button19_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
        }

        private void checkBoxSaveVideoAsImage_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void buttonMultipleCam_Click(object sender, EventArgs e)
        {
           
        }

        private void buttonCapToBuffer_Click(object sender, EventArgs e)
        {
            //byte[] buffer = new byte[1024 * 1024 * 2];
            //int len = 0;
            //HaSdk.HA_CapImgToBuffer(g_cam, buffer, ref len);
            //if (len > 0)
            //{
            //    string file = Path.GetTempFileName() + ".jpg";
            //    File.WriteAllBytes(file, buffer);
            //    Process.Start(file);
            //}
        }

        private void buttonLightOff_Click(object sender, EventArgs e)
        {
            var suc = axHaCamera1.VzLPRSerialSend(0, "ff00000000000000", 0);
            Log("发送结果：" + suc);
        }

        private void buttonLightOn_Click(object sender, EventArgs e)
        {
            var suc = axHaCamera1.VzLPRSerialSend(0, "ff00510000000051", 0);
            Log("发送结果：" + suc);
        }

        private void axHaCamera1_OnLPRPlateInfoOutEx2(object sender, AxHaCameraLib._DHaCameraEvents_OnLPRPlateInfoOutEx2Event e)
        {
			Log("收到车牌: " + e.license);
            var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "OcxPlates.txt");
            using (var file = File.AppendText(path))
            {
                var license = string.IsNullOrEmpty(e.license)?"无牌":e.license;
                var msg = string.Format("{0} {1} {2}", license, e.plateTime, e.ip);
                file.WriteLine(msg);
            }
            if (!string.IsNullOrEmpty(e.imagePath))
            {
                var img = Image.FromStream(new MemoryStream(File.ReadAllBytes(e.imagePath)));
                var plate = new PlateCaptured();
                plate.image = img;
                plate.hphm = e.license;
                if (File.Exists(e.imgPlatePath))
                {
                    plate.plateImage = Image.FromStream(new MemoryStream(File.ReadAllBytes(e.imgPlatePath)));
                }

                plate.colorIndex = e.colorIndex;
                ShowPlate(plate);
            }

        }


        class PlateCaptured
        {
            public string hphm;
            public Image image;
            public int colorIndex;
            public Image plateImage;
        }

        private void axHaCamera1_OnImageDecoded(object sender, AxHaCameraLib._DHaCameraEvents_OnImageDecodedEvent e)
        {
            var old = pictureBoxRealtime.Image;
            if (File.Exists(e.imagePath))
            {
                var mem = File.ReadAllBytes(e.imagePath);
                var img = Image.FromStream(new MemoryStream(mem));
                pictureBoxRealtime.Image = img;
            }
            if (old != null)
            {
                old.Dispose();
            }

        }

        private void axHaCamera1_Log(object sender, AxHaCameraLib._DHaCameraEvents_LogEvent e)
        {
            Log(e.message);
        }

        private void axHaCamera1_OnLPRWlistInfoOut(object sender, AxHaCameraLib._DHaCameraEvents_OnLPRWlistInfoOutEvent e)
        {
            var msg = e.strPlateID + " " + e.strOverDue;
            Log(msg);
        }

        private void buttonDelWlist_Click(object sender, EventArgs e)
        {
            var res = axHaCamera1.VzLPRClientDeleteWlist(textBoxHphm.Text, 0);
            LogResult(res);
        }

        private void buttonUpdate_Click(object sender, EventArgs e)
        {
            var result = axHaCamera1.VzLPRClientUpdateWlist(textBoxHphm.Text, 0, false, "1974-12-31 00:00:00", false, true, "", 0, 0);
            LogResult(result);
        }

        private void buttonPlayAudio_Click(object sender, EventArgs e)
        {
            var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.wav");
            var result = axHaCamera1.PlayAudioFile(path);
            LogResult(result);
        }

        private void buttonSetSerialParameters_Click(object sender, EventArgs e)
        {
            axHaCamera1.VzLPRSetSerialParameter(0, 0, 9600, 0, 8, 1);
        }

        private void buttonSetDateTime_Click(object sender, EventArgs e)
        {
            var res = axHaCamera1.VzLPRSetDateTime(0, textBoxDateTime.Text);
            LogResult(res);
        }

        private void buttonFindDevice_Click(object sender, EventArgs e)
        {
            ipList.Clear();
            axHaCamera1.VzLPRStopFindDevice();
            axHaCamera1.VzLPRStartFindDevice();
        }



        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            axHaCamera1.VzLPRStopFindDevice();
        }

        private void buttonBatchAddWlist_Click(object sender, EventArgs e)
        {
            var prefix = "川A123";
            for (int i = 0; i < 10; i++)
            {
                var hphm = string.Format("{0}{1:D2}", prefix, i);
                var result = axHaCamera1.VzLPRClientAddWlist(hphm, 0, true, "2016-12-31 12:23:34", false, false, "", 0);
                LogResult(result);
            }
        }

        private void axHaCamera1_OnLPRSerialRecvData(object sender, AxHaCameraLib._DHaCameraEvents_OnLPRSerialRecvDataEvent e)
        {
            this.listBoxSerialReceived.Items.Add(e.recvData);
        }

        private void axHaCamera1_OnLPRPlateImgOut(object sender, AxHaCameraLib._DHaCameraEvents_OnLPRPlateImgOutEvent e)
        {
            //this.Log(string.Format("收到抓拍图片：{0}", e.imagePath));
        }

        private void button20_Click(object sender, EventArgs e)
        {
            var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                DateTime.Now.ToString("yy-MM-dd_HHmmss") + ".avi");
            var suc = axHaCamera1.VzLPRSaveRealData(0, path);
            LogResult(suc);
        }

        private void button21_Click(object sender, EventArgs e)
        {
            var suc = axHaCamera1.VzLPRStopSaveRealData(0);
            LogResult(suc);
        }

        private void axHaCamera1_OnLPRQueryPlateInfoOut(object sender, AxHaCameraLib._DHaCameraEvents_OnLPRQueryPlateInfoOutEvent e)
        {
            var msg = string.Format("查询结果 号牌: {0}", e.license);
            Log(msg);
        }

        private void axHaCamera1_OnLPROfflinePlateInfoOut(object sender, AxHaCameraLib._DHaCameraEvents_OnLPROfflinePlateInfoOutEvent e)
        {
            var msg = string.Format("离线结果 号牌: {0}", e.license);
            Log(msg);
        }

        private void buttonQuery_Click(object sender, EventArgs e)
        {
            var count = axHaCamera1.VzLPRQueryCountByTimeAndPlate(0, textBoxQueryFrom.Text, textBoxQueryTo.Text, "川");
            Log(string.Format("总共查询到{0}条", count));
            var res = axHaCamera1.VzLPRQueryRecordByTimeAndPlate(0, textBoxQueryFrom.Text, textBoxQueryTo.Text, "川");
            LogResult(res);
        }

        private void checkBoxWriteLog_CheckedChanged(object sender, EventArgs e)
        {
            axHaCamera1.EnableLogToFile(checkBoxWriteLog.Checked);

            axHaCamera1.SetPlateLogDir(AppDomain.CurrentDomain.BaseDirectory);
        }

        private void buttonGetTime_Click(object sender, EventArgs e)
        {
            string time = axHaCamera1.VzLPRGetDateTime(0);
            Log(string.Format("获取时间：{0}", time));
        }
		
		private void buttonAutoTrigger_Click(object sender, EventArgs e)
        {
            using(var form = new FormAutoTrigger())
            {
                if (form.ShowDialog(this) == DialogResult.OK)
                {
                    var seconds = float.Parse(form.textBoxTriggerInterval.Text);
                    timerTrigger.Interval = Convert.ToInt32(seconds * 1000);
                    timerTrigger.Enabled = true;

                }

            }
        }

        private void timerTrigger_Tick(object sender, EventArgs e)
        {
            axHaCamera1.VzLPRClientForceTrigger(0);
        }

        private void buttonClearWlistFromMem_Click(object sender, EventArgs e)
        {
            axHaCamera1.VzLPRClientRemoveWlistFromArray(0);
        }

        private void buttonAddWlistFromMem_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 100; i++)
			{
                var cam = string.Format("川A00{0:d3}", i);
                var res = axHaCamera1.VzLPRClientAddWlistToArray(cam, 0, true, "2017-12-31 12:00:00", true, true, "", 0);
                if (res != 0)
                {
                    throw new Exception("添加白名单到内存发生异常");
                }
			}

            var res1 = axHaCamera1.VzLPRClientBatchImportWlistFromArray(0);
            LogResult(res1);

            
        }
    }
}
